#pragma once
// Qt headers
#include <QPoint>
#include <QObject>
#include <QMap>
// Ogre headers
#include <Ogre.h>
// Constants
#define DEFAULT_DRAG_MOVE_SPEED 10
#define DEFAULT_ROTATE_SPEED 50
#define MOVABLE_TEXT "MovableText"
#define SHOULD_NOT_CLICKED "ShouldNotClicked"
#define SIMPLE_RENDERABLE "SimpleRenderable"
#define STR_NOT_FOUND std::string::npos

class DIVA_VM;
class KeyboardAction;
class QWheelEvent;
// 2012/1/7 Luke
// The contract in QxTesting Capture-Replay module requires that the caller
// of xInput(...) to be a QObject, and the calling method must contain 
// arguments that can be serialized to a JSON object.
// Therefore, the following changes have been made:
// 1. Made this object a subclass of QObject.
// 2. Change the method parameter signatures of mouse / keyboard event from 
//    QMouseEvents to integers.


class QDivaAppController: public QObject{
	Q_OBJECT
public:	
	enum DRAGGING_MODE{DRAG_FORWARD, DRAG_BACKWARD, DRAG_TO_NEW_POS};
	// Constructor and Destructor
	QDivaAppController();
	virtual ~QDivaAppController();	
	void init(Ogre::SceneManager*  ,Ogre::Camera*);
	// Mouse / keyboard event call back functions
	virtual void mouseLeftButtonPressed(int mouseX, int mouseY);
	virtual void mouseLeftButtonReleased(int mouseX, int mouseY);
	virtual void mouseRightButtonPressed(int mouseX, int mouseY);
	virtual void mouseRightButtonReleased(int mouseX, int mouseY);
	virtual void mouseMoving(int mouseX, int mouseY);
	virtual void keyboardPressed(int key);
	virtual void keyboardReleased(int key);
	virtual void mouseWheelRotated(int delta);
	virtual void changeBackground( const QString& newBackground );
	// methods
	bool isLeftButtonPressed();
	void dragVM(DRAGGING_MODE mode);
	void stopWheelZooming();
	int zoomLevel(); // getter for _zoomLevel
	DIVA_VM* getCorrectVM(); //for explorbot

signals:
	void rightClicked(DIVA_VM*);
protected:
	static int instanceCount; // counts the instances of this class
	// Attributes	
	Qt::MouseButton _currentMouseBtn;
	QMap<int, KeyboardAction*> _keyboardActions;
	QPoint _mouseNewPos;
	QPoint _mouseOldPos;
	Ogre::Camera *_camera;
	Ogre::MovableObject *_currentMovableObj;
	Ogre::SceneNode *_currentSelectedObj; 
	Ogre::Vector3 _distance;
	Ogre::RaySceneQuery *_query;
	Ogre::SceneManager *_sceneMgr;
	DIVA_VM *_currentVM;
	bool _isZooming;
	int _zoomLevel;
	// Methods
	bool isValidObjName( const Ogre::String &currentObjName );
	void calculateDistance();
	void collisionHandling( );
	void dispatchClickEvent( const QPointF &mousePos );
	void doDynamicLayout( );
	void initKeyboardActions();
	void moveCurrentSelectedObj( );
	void queryForMovableObj( const QPointF &mousePos);	
	void rotateCamera();
	Ogre::Vector3 computeAbsPos( DRAGGING_MODE mode );
	// for mouse wheel zooming
	bool isWheelRotatedForwards( QWheelEvent &evt );
	bool isWheelRotatedBackwards( QWheelEvent &evt );
	
};

